/*
 * Copyright 2008 the Breachwalls OSS project and the Others.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
 * either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */
package com.breachwalls.mogen.utils;

import org.apache.commons.lang.StringUtils;

/**
 * Java 命名規約に関するユーティリティ.
 * @author todoken
 * @version $Revision: 31 $
 */
public final class JavaNameUtils {

    /**
     * コンストラクタ.
     */
    private JavaNameUtils() {
    }

    /**
     * Java 名称から RDB 名称に変換する.
     * @param name 変換する名称
     * @return RDM で使用できるように変換した名称
     */
    public static String toRdbName(String name) {
        if (StringUtils.isEmpty(name)) {
            return name;
        }

        if (StringUtils.contains(name, '_')) {
            return StringUtils.upperCase(name);
        }

        final StringBuffer buffer = new StringBuffer();
        for (int i = 0; i < name.length(); i++) {
            char c = name.charAt(i);
            if (i != 0 && Character.isUpperCase(c)) {
                buffer.append('_');
                buffer.append(c);
            } else {
                buffer.append(Character.toUpperCase(c));
            }
        }

        return buffer.toString();
    }

    /**
     * RDB 名称から Java 名称に変換する.
     * @param name 変換する名称
     * @return Java で使用できるように変換した名称
     */
    public static String toJavaName(final String name) {
        if (StringUtils.isEmpty(name)) {
            return name;
        }

        if (!StringUtils.contains(name, '_')) {
            return name;
        }

        boolean separator = false;
        final StringBuffer buffer = new StringBuffer();
        for (int i = 0; i < name.length(); i++) {
            char c = name.charAt(i);
            if (c == '_') {
                separator = true;
            } else if (separator) {
                buffer.append(Character.toUpperCase(c));
                separator = false;
            } else {
                buffer.append(Character.toLowerCase(c));
            }
        }

        return buffer.toString();
    }

    /**
     * Java のフィールド命名規約に沿った名称に変換する.
     * @param name 変換する名称
     * @return Java フィールド名に変換した名称
     */
    public static String toJavaFieldName(String name) {
        if (StringUtils.isEmpty(name)) {
            return name;
        }

        if (StringUtils.contains(name, '_')) {
            name = toJavaName(name);
        }

        boolean separator = false;
        final StringBuffer buffer = new StringBuffer();
        for (int i = 0; i < name.length(); i++) {
            char c = name.charAt(i);
            if (i == 0) {
                buffer.append(Character.toLowerCase(c));
            } else if (c == '_') {
                separator = true;
            } else if (separator) {
                buffer.append(Character.toUpperCase(c));
            } else {
                buffer.append(c);
            }
        }

        return buffer.toString();
    }

    /**
     * Java のメソッド命名規約に沿った名称に変換する.
     * @param name 変換する名称
     * @return Java メソッド名に変換した名称
     */
    public static String toJavaMethodName(String name) {
        if (StringUtils.isEmpty(name)) {
            return name;
        }

        if (StringUtils.contains(name, '_')) {
            name = toJavaName(name);
        }

        final StringBuffer buffer = new StringBuffer();
        for (int i = 0; i < name.length(); i++) {
            char c = name.charAt(i);
            if (i == 0) {
                buffer.append(Character.toUpperCase(c));
            } else if (Character.isUpperCase(c)) {
                buffer.append(c);
            } else {
                buffer.append(Character.toLowerCase(c));
            }
        }

        return buffer.toString();
    }

    /**
     * Java のフィールド命名規約に沿った名称に変換する. また、コレクション型の名称に対応している.
     * @param name 変換する名称
     * @return Java フィールド名に変換したコレクション名称
     */
    public static String toCollectionFieldName(String name) {
        if (StringUtils.isEmpty(name)) {
            return name;
        }

        name = toJavaFieldName(name);

        StringBuffer buffer = new StringBuffer();
        if (StringUtils.endsWith(name, "y")) {
            for (int i = 0; i < name.length() - 1; i++) {
                char c = name.charAt(i);
                buffer.append(c);
            }
            buffer.append("ies");
        } else if (StringUtils.endsWith(name, "s") || StringUtils.endsWith(name, "ss")
                || StringUtils.endsWith(name, "sh") || StringUtils.endsWith(name, "ch")
                || StringUtils.endsWith(name, "o") || StringUtils.endsWith(name, "x")) {
            buffer.append(name);
            buffer.append("es");
        } else if (StringUtils.endsWith(name, "f")) {
            for (int i = 0; i < name.length() - 1; i++) {
                char c = name.charAt(i);
                buffer.append(c);
            }
            buffer.append("ves");
        } else if (StringUtils.endsWith(name, "fe")) {
            for (int i = 0; i < name.length() - 2; i++) {
                char c = name.charAt(i);
                buffer.append(c);
            }
            buffer.append("ves");
        } else {
            buffer.append(name);
            buffer.append("s");
        }

        return buffer.toString();
    }

}
